import json
import time
import os
import sys
import configparser
import requests
import traceback
import threading
import random
import logging

from core.browser_manager import BrowserManager as BM
from core.task_executor import TaskExecutor as TE
from core.baidu_cuttlefish import BaiduCuttlefish as BC
from core.api_client import ApiClient as AC
from bin.generate_article_thread_api import create_articles,create_task_articles,create_one_task_articles
from bin.login_manager import add_account
# 设置基础目录
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 读取配置文件
config.read('config.ini')

class WenkuManager:
	def __init__(self):
		"""初始化WenkuManager实例"""
		self.uid = None
		self.token = None
		self.ac = AC()
		self.account_list = []
		self.bot_list = []
		self.driver = None
		self.generate_model_list=[]
		self._login()
		self._set_infos()

	def _login(self):
		while True:
			username = str(input("请输入账号：")).strip()
			password = str(input("请输入密码：")).strip()
			data = {"username": username, "password": password, "timeout": 36000}
			# data = {'username': username, 'password': password, 'timeout': 36000}
			if not username or not password:
				print("请重新输入")
				continue
			token = requests.post("http://101.126.16.255/api/v1/login",data=data).json()
			# print(token)
			if int(token['code']):
				print(token['msg'])
				continue
			self.token = token['token']
			self.ac.token = self.token
			user_info = self.ac.get_data(endpoint="/api/wenku/user/get_user_info", username = username)
			# print(user_info)
			self.uid = user_info['id']
			break


	def _set_infos(self):
		"""登录并获取账号和机器人列表"""
		if self.uid:
			self.account_list = self.ac.get_data(endpoint="/api/wenku/account/get_accounts_list", user_id=self.uid)
			self.bot_list = self.ac.get_data(endpoint="/api/wenku/coze_bot/get_coze_list")
			self.generate_model_list = self.ac.get_data(endpoint="/api/wenku/coze_bot/get_generate_model")
			print(f"------已获取到{len(self.account_list)}个账号------")
			for account in self.account_list:
				print(f"账号{account['uname']}:文档{account['doc_num']}个-被下载{account['be_download_num']}次-定力任务状态{account['is_task_able']}-下载券{account['ticket_num']}")
		else:
			exit()

	def account_management(self):
		"""处理账号管理选项-11、更新cookie(未做)"""
		lever_2 = int(input("""
-10、登录查看
-12、更新账号信息
-15、更新任务状态
-99、返回
请输入对应的数字：
        """))

		if lever_2 == 10:
			self.view_login()
		# elif lever_2 == 11:
		# 	self.update_cookies()
		elif lever_2 == 12:
			self.update_infos()
		elif lever_2 == 15:
			self.update_task_is_finish()
	def view_login(self):
		"""登录查看账号"""
		options = [(i + 1, account['uname']) for i, account in enumerate(self.account_list)]
		for index, name in options:
			print(f"{index}、{name}")

		choice = input("请选择要操作的账号（输入序号）: ")
		try:
			choice = int(choice) - 1
			if 0 <= choice < len(self.account_list):
				bm = BM(cookie=self.account_list[choice]['cookie'], is_headless=0, target_type=1)
				self.driver = bm.driver
				while True:
					if int(input("请输入1关闭浏览器：")) == 1:
						self.driver = None
						bm = None
						break
			else:
				print("无效的选项，请重新选择。")
		except ValueError:
			print("请输入一个有效的数字序号。")

	def update_infos(self):
		for item in self.account_list:
			# 示例代码，实际代码需要补全
			bc = BC(item['cookie'])
			bc.get_all_info()
			user_info = bc.user_info
			# print(user_info)
			# print(type(user_info))
			print(f"========开始更新账号<{item['uname']}>========")
			res=self.ac.post_data(endpoint="/api/wenku/account/updateByCond", data=user_info)
			print(res)
			print(f"========账号<{item['uname']}>更新完成========")
			time.sleep(3)

	def update_task_is_finish(self):
		for item in self.account_list:
			# 示例代码，实际代码需要补全
			print(f"========开始更新账号<{item['uname']}>========")
			bc = BC(item['cookie'])
			bc.get_is_task_finish()
			user_info = bc.user_info
			user_info['uid'] = item['uid']
			# print(user_info)
			# print("服务器发请求")
			res=self.ac.post_data(endpoint="/api/wenku/account/updateByCond", data=user_info)
			print(res)
			print(f"========账号<{item['uname']}>更新完成========")
			time.sleep(3)

	def update_cookies(self):
		"""更新账号cookie"""
		pass

	def generate_articles(self):
		"""处理文章生成选项"""
		#21、生成原力任务文章，从数据库获取标题自动生成(做任务用的)-OLD
		lever_2 = int(input("""
-21、输入标题生成文章
-22、按照账号id生成原力任务文章，从数据库获取标题自动生成(做任务用的)
-23、先筛查任务是否已完成，再进行创作(待测试)。
-99、返回
请输入对应的数字：
        """))

		if lever_2 == 21:
			self.generate_custom_articles()
		elif lever_2 == 22:
			self.generate_task_articles_multi()
		elif lever_2 ==23:
			self.generate_task_articles_last()

	# def generate_task_articles(self):
	# 	"""从数据库获取标题并生成文章,只写英文的"""
	# 	title_list = self.ac.get_data(endpoint="/api/wenku/titles/get_titles_list", ai_score=10)
	# 	print(f"------已获取到{len(title_list)}个10分的写作任务------")
	# 	task_list = [item['article_name'] for item in title_list]
	# 	model = self.generate_model_list[1]
	#
	# 	output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files')
	# 	# output_dir = os.path.join(config['path']['doc_dir'], 'task_files')
	# 	create_articles(task_list, self.bot_list, output_dir=output_dir,model=model)
	#获取任务文章list
	def generate_task_articles_multi(self):
		"""从数据库获取标题并生成文章,只写英文的"""
		title_list = self.ac.get_data(endpoint="/api/wenku/titles/get_titles_list", ai_score=10)#,user_id = self.uid
		print(f"------已获取到{len(title_list)}个10分的写作任务------")
		model = self.generate_model_list[1]
		# print(model)
		output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files')
		create_task_articles(title_list, self.bot_list, output_dir=output_dir,model=model)
	def generate_task_articles_last(self):
		"""个别账号、个别文章单独生成"""
		title_list_new=[]
		for account in self.account_list:
			if not account['is_task_finish']:
				continue
			title_list = self.ac.get_data(endpoint="/api/wenku/titles/get_titles_list", ai_score=10,account_id = account['uid'])
			bc = BC(account['cookie'])
			print(f"------<{account['uname']}>已获取到{len(title_list)}个10分的写作任务------")
			#任务过滤
			for item in title_list:
				time.sleep(4)
				if not bc.check_task_is_available(item):
					print(f"<{account['uname']}>的任务《{item['article_name']}》已被人完成，换下一个；")
					continue
				else:
					print(f"<{account['uname']}>的任务《{item['article_name']}》未被人完成，可以创作；")
					title_list_new.append(item)
		print(f"筛选到{len(title_list_new)}个任务，马上进行创作")
		model = self.generate_model_list[1]
		output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files')
		create_task_articles(title_list_new, self.bot_list, output_dir=output_dir,model=model)
	# 输入标题|标题进行创作
	def generate_custom_articles(self):
		"""根据用户输入生成文章"""
		options = [(i + 1, model['name']) for i, model in enumerate(self.generate_model_list)]
		for index, name in options:
			print(f"{index}、{name}")
		choice = input("请选择文章创作模型（输入序号）: ")
		try:
			choice = int(choice) - 1
			if 0 <= choice < len(self.generate_model_list):
				model = self.generate_model_list[choice]
				title_list = input("请输入文章标题，多个的话用‘|’分隔开:").split('|')
				create_articles(title_list, self.bot_list,model=model)

			else:
				print("无效的选项，请重新选择。")
		except ValueError:
			print("请输入一个有效的数字序号。")

	def manage_tasks(self):
		"""处理任务管理选项"""#38、自动化原力任务-多线程-边生成边上传（待开发）
		lever_2 = int(input("""
-31、为单个用户上传VIP文档
-32、为所有用户上传VIP文档-单线程
-33、为所有用户上传VIP文档-多线程
-34、自动化原力任务-单线程
-35、自动化原力任务-多线程
-38、自动化原力任务-多线程-边生成边上传（待测试）
-36、删除未通过的文档
-37、VPI文档下载任务（一个账号下载另一个的）
-99、返回
请输入对应的数字：
        """))

		if lever_2 == 31:
			self.upload_vip_docs_for_single_user()
		elif lever_2 == 32:
			self.upload_vip_docs_for_all_users()
		elif lever_2 == 33:
			self.upload_vip_docs_for_all_users_thread()
		elif lever_2 == 34:
			self.automate_task_multi()
		elif lever_2 == 35:
			self.automate_task_multi_thread()
		elif lever_2 == 38:
			self.automate_task_multi_thread_gc()
		elif lever_2 == 36:
			self.delete_failed_docs()
		elif lever_2 == 37:
			self.download_vip_docs()

	def upload_vip_docs_for_single_user(self):
		"""为单个用户上传VIP文档"""
		options = [(i + 1, account['uname']) for i, account in enumerate(self.account_list)]
		for index, name in options:
			print(f"{index}、{name}")
		choice = input("请选择要操作的账号（输入序号）: ")
		try:
			choice = int(choice) - 1
			if 0 <= choice < len(self.account_list):
				num = int(input("请填写要上传的文档数量："))
				folder_name = str(input("请输入doc_files下的文件名："))
				if not folder_name:
					folder_name = "vip_files"
				if num:
					is_headless = int(input("是否无界面？（1无界面、0打开浏览器）："))
					driver = BM(is_headless=is_headless, cookie=self.account_list[choice]["cookie"], target_type=1)
					print(f"选定账号：{self.account_list[choice]['uname']}")
					folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files',folder_name)
					TE(driver = driver.driver, folder_path=folder_path,upload_limit=num, task_type=1, account=self.account_list[choice], ac= self.ac)
			else:
				print("无效的选项，请重新选择。")
		except ValueError:
			print("请输入一个有效的数字序号。")

	def upload_vip_docs_for_all_users(self):
		"""为每个用户上传VIP文档"""
		num = int(input("请填写要上传的文档数量："))
		is_headless = int(input("是否无界面？（1无界面、0打开浏览器）："))
		folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files','vip_files')
		if num:
			for item in self.account_list:
				if item['is_vipdoc_finish']:
					continue
				driver = BM(is_headless=is_headless, cookie=item["cookie"], target_type=1)
				print(f"======选定账号：{item['uname']}======")
				TE(driver.driver, folder_path=folder_path,upload_limit=num, task_type=1,account=item, ac=self.ac)#"C:\\Users\\Administrator\\Desktop\\july\\doc_files\\vip_files"
				time.sleep(30)

	def _upload_vip_docs_for_all_users_thread_process(self,account,files_list):
		print(f"选定账号：{account['uname']},执行上传任务")
		driver = BM(is_headless=1, cookie=account["cookie"], target_type=1)
		TE(driver.driver,files_list=files_list, upload_limit=1000, task_type=1, account=account,ac=self.ac)
		time.sleep(30)

	def upload_vip_docs_for_all_users_thread(self):
		"""为每个用户上传VIP文档,多线程"""
		folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files','vip_files')
		files = []  # 用于存储文件的完整路径
		for root, dirs, file_names in os.walk(folder_path, topdown=True):  # 只遍历顶层
			for file_name in file_names:
				file_path = os.path.join(root, file_name)
				files.append(file_path)
			break  # 只遍历顶层文件夹
		random.shuffle(files)

		accounts = [item for item in self.account_list if item['is_vipdoc_finish'] == 0]

		# 确保线程数量不超过文件数量
		num_threads = min(len(accounts), len(files))
		if num_threads == 0:
			print(f"文件数量为{len(files)}；账号数量为{len(accounts)}；无法创建线程。")
			return
		chunk_size = len(files) // num_threads
		file_chunks = [files[i * chunk_size:(i + 1) * chunk_size] for i in range(num_threads)]
		# 处理最后一个线程可能多出来的文件
		file_chunks[-1].extend(files[num_threads * chunk_size:])

		# 创建线程并执行
		threads = []
		for i, account in enumerate(accounts):
			thread = threading.Thread(target=self._upload_vip_docs_for_all_users_thread_process, args=(account, file_chunks[i]))
			threads.append(thread)
			thread.start()

		# 等待所有线程完成
		for thread in threads:
			thread.join()

	def automate_task(self):
		"""自动化原力任务"""
		options = [(i + 1, account['uname']) for i, account in enumerate(self.account_list)]
		for index, name in options:
			print(f"{index}、{name}")
		choice = input("请选择要操作的账号（输入序号）: ")
		choice = int(choice) - 1
		if 0 <= choice < len(self.account_list):
			if self.account_list[choice]['is_task_finish']:
				print("该账号今天已经完成任务，请明天再来")
				return
			is_headless = int(input("是否无界面？（1无界面、0打开浏览器）："))
			driver = BM(is_headless=is_headless, cookie=self.account_list[choice]["cookie"], target_type=2)
			print(f"选定账号：{self.account_list[choice]['uname']}")
			folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files')
			TE(driver.driver, folder_path=folder_path,upload_limit=50, task_type=2, ac=self.ac)
		else:
			print("无效的选项，请重新选择。")

	def automate_task_multi(self):
		"""自动化原力任务"""
		is_headless = int(input("是否无界面？（1无界面、0打开浏览器）："))
		for account in self.account_list:
			if account['is_task_finish']:
				continue
			print(f"======选定账号：{account['uname']}(uid:{account['uid']})======")
			driver = BM(is_headless=is_headless, cookie=account["cookie"], target_type=2)
			folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files',account['uid'])
			TE(driver.driver, folder_path=folder_path,upload_limit=50, task_type=2, ac=self.ac,account = account)
			driver.driver.quit()
			time.sleep(5)


	def automate_task_multi_thread_process(self,account):
		# 多线程
		print(f"======选定账号：{account['uname']}(uid:{account['uid']})======")
		driver = BM(is_headless=1, cookie=account["cookie"], target_type=2)
		folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files', account['uid'])
		TE(driver.driver, folder_path=folder_path, upload_limit=50, task_type=2, ac=self.ac, account=account)
		# driver.driver.quit()
		time.sleep(5)

	def automate_task_multi_thread(self):
		"""自动化原力任务--多线程版本"""
		threads = []
		print('-------------------------------')
		for account in self.account_list:
			if not account['is_task_finish']:
			# if account['is_task_finish']:
				thread = threading.Thread(target=self.automate_task_multi_thread_process, args=(account,))
				threads.append(thread)
				thread.start()

		# 等待所有线程完成
		for thread in threads:
			thread.join()

	def automate_task_multi_thread_process_gc(self,account):
		# 多线程
		print(f"======选定账号：{account['uname']}(uid:{account['uid']})======")
		# 获取该用户的任务
		task_list = self.ac.get_data(endpoint="/api/wenku/titles/get_titles_list", account_id=account['uid'])
		print(f"======账号：{account['uname']}(uid:{account['uid']})查询到{len(task_list)}个任务======")
		driver = BM(is_headless=1, cookie=account["cookie"], target_type=2)
		random.shuffle(task_list)
		for item in task_list:
			# if item['is_finish'] != 0:
			# 	print(f"<{account['uname']}>的任务《{item['article_name']}》已完成，换下一个；")
			# 	continue
			#首先检查该任务是否已经上传
			bc = BC(account['cookie'])
			if not bc.check_task_is_available(item):
				print(f"<{account['uname']}>的任务《{item['article_name']}》已被人完成，换下一个；")
				time.sleep(4)
				continue
			# time.sleep(5)
			#开始生成文档
			folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'doc_files', 'task_files',account['uid'])
			spath = create_one_task_articles(task_title=item,bot_infos=self.bot_list,output_dir=folder_path,model=self.generate_model_list[1])
			# if not spath:
			# 	continue
			# print(spath)
			files_list = []
			files_list.append(spath)
			te = TE(driver.driver, files_list=files_list, upload_limit=50, task_type=3, ac=self.ac, account=account)
			if not te.task_able:
				return False
			time.sleep(5)

	def automate_task_multi_thread_gc(self):
		"""自动化原力任务--多线程版本--边生成边上传,一个账号一个线程"""
		threads = []
		print('-------------------------------')
		for account in self.account_list:
			if not account['is_task_finish']:
			# if account['is_task_finish']:
				thread = threading.Thread(target=self.automate_task_multi_thread_process_gc, args=(account,))
				threads.append(thread)
				thread.start()
		# 等待所有线程完成
		for thread in threads:
			thread.join()
	def delete_failed_docs(self):
		"""删除未通过的文档"""
		num = int(input("请填写要检查的页数（推荐5）："))
		if num:
			for item in self.account_list:
				print(f"选定账号：{item['uname']}")
				bc = BC(cookie_str=item["cookie"])
				print(bc.del_fail_article(total_page=num))
				time.sleep(10)

	def download_vip_docs(self):
		"""下载任务"""
		options = [(i + 1, account['uname']) for i, account in enumerate(self.account_list)]
		for index, name in options:
			print(f"{index}、{name}")
		choice1 = int(input("请选择下载的账号: ")) - 1
		choice2 = int(input("请选择被下载的账号: ")) - 1
		num = int(input("请录入下载的次数: "))
		is_headless = int(input("是否无界面？（1无界面、0打开浏览器）："))

		if 0 <= choice1 < len(self.account_list) or 0 <= choice2 < len(self.account_list):
			driver = BM(is_headless=is_headless, cookie=self.account_list[choice1]["cookie"], target_type=0)
			bc = BC(cookie_str=self.account_list[choice2]["cookie"])
			docs = bc.get_article(10)
			te = TE(driver=driver.driver,task_type=0)
			te.download_vip_file(docs,num)
		else:
			print("无效的选项，请重新选择。")

	def get_checked_titles(self):
		"""获取已上架的标题"""
		num = int(input("请填写每个账号统计的页数（推荐5）："))
		titles_array = []
		if num:
			for item in self.account_list:
				print(f"选定账号：{item['uname']}")
				bc = BC(cookie_str=item["cookie"])
				articles = bc.get_article(num)
				for article in articles:
					if article["doc_status"] == 2:
						#并且title中包括"0"、"选"、"题"
						if "0" in article["title"] or "选" in article["title"] or "题" in article["title"]:
							titles_array.append(article["title"])
				if len(titles_array) > 150:
					print(f"获取到{len(titles_array)}个标题")
					print('|'.join(titles_array))
					titles_array = []
		if len(titles_array) > 100:
			print(f"获取到{len(titles_array)}个标题")
			print('|'.join(titles_array))

	def get_everyday_task_num(self):
		driver = BM(is_headless=1, cookie=self.account_list[0]["cookie"], target_type=2)
		res = driver.get_task_num()
		if res:
			print(res)
			res1 = self.ac.post_data(endpoint="/api/wenku/account/updateEveryDayTaskNum", data=res)
			print(res1)

	def main_menu(self):
		"""主菜单"""
		while True:
			lever_1 = int(input("""
1、账号管理
2、文章生成
3、任务管理
9、已上架的标题
20、查询每天任务数量（待开发）
0、退出程序
请输入对应数字：
"""))
			if lever_1 == 0:
				break
			elif lever_1 == 1:
				self.account_management()
			elif lever_1 == 2:
				self.generate_articles()
			elif lever_1 == 3:
				self.manage_tasks()
			elif lever_1 == 9:
				self.get_checked_titles()
			elif lever_1 == 20:
				self.get_everyday_task_num()
			elif lever_1 == 186:
				add_account(self.ac)
			elif lever_1 == 188:
				BM(is_headless=0)
				while True:
					if int(input("是否关闭浏览器（1是，0否）：")) == 1:
						break
					else:
						continue


if __name__ == "__main__":
	# uid = int(input("请输入UID："))

	try:
		manager = WenkuManager()
		manager.main_menu()
	except FileNotFoundError as e:
		traceback.print_exc()
		print(f"文件未找到错误：{e}")
	except PermissionError as e:
		traceback.print_exc()
		print(f"权限错误：{e}")
	except Exception as e:
		traceback.print_exc()
		print(f"其他错误：{e}")

	# while True:
	# 	if int(input("是否结束：")) == 1:
	# 		break